﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using BrainTechLLC;
using System.Windows.Threading;
using System.Windows;
using BrainTechLLC.ThreadSafeObjects;
using System.Threading;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.Serialization;

namespace BrainTechLLC
{
    [Serializable]
    [DataContract]
    public class ClassAndPropertyChange
    {
        [DataMember]
        public string PropertyName;
        [DataMember]
        public BaseNotifyPropertyChanged ClassObject;

        public virtual bool EqualsOther(ClassAndPropertyChange other)
        {
            return (PropertyName == other.PropertyName) && (ClassObject == other.ClassObject);
        }

        public ClassAndPropertyChange(BaseNotifyPropertyChanged classObject, string propertyName)
        {
            ClassObject = classObject;
            PropertyName = propertyName;
        }

        public virtual void RaisePropertyChanged()
        {
#if SILVERLIGHT
            ClassObject.RaisePropertyChanged(PropertyName);         
#else
            if (ClassObject._propertyChanged != null && ClassObject._propertyChanged.eventEntries.Count > 0)
            {
                ClassObject.RaisePropertyChanged(PropertyName);
            }
#endif
        }
    }

    [Serializable]
    [DataContract]
    public class ClassAndPropertyChangeCollection
    {
        [DataMember]
        // candidate for conversion to dictionary lookup by property name if list is frequently large
        public ThreadSafeListAndLookup<object, ClassAndPropertyChange> PropertyChanges = new ThreadSafeListAndLookup<object, ClassAndPropertyChange>();

        public void AddPropertyChange(ClassAndPropertyChange propChange)
        {
            var list = PropertyChanges[propChange.ClassObject];
            if (list != null)
            {
                for (int n = list.Count - 1; n >= 0; n--)
                {
                    var p = list[n];

                    if (propChange.EqualsOther(p))
                        return;
                }
            }
            else
            {
            }

            PropertyChanges.Add(propChange.ClassObject, propChange);
        }

        public void RunAllPropertyChanges()
        {
            var all = PropertyChanges.AllItems;

            for (int n = 0; n < all.Count; n++)
            {
                var p = all[n];
                p.RaisePropertyChanged();
            }

            PropertyChanges.Clear();
        }
    }
}
